package com.zlp.config;

import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import com.zlp.common.constants.OSSConstant;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
public class OSSTemplate {

	@Resource
	private  OSSClient ossClient;

	public OSSTemplate(OSSClient ossClient) {
		this.ossClient = ossClient;
	}
	/**
	 * 目前所有文件都存放在该命名空间下
	 */
	private final static String bucketName = OSSConstant.BUCKE_NAME;

	/**
	 *  上传文件
	 * @param bucketName  仓库名称
	 * @param fileUrl   生成文件url
	 * @param input		InputStream
	 * @date: 2021/3/19 10:39
	 * @return: void
	 */
	@SneakyThrows
	public void putObject(String bucketName, String fileUrl, InputStream input) {

		ossClient.putObject(bucketName, fileUrl, input);
	}
	/**
	 * 上传文件带进度条
	 * @param bucketName 仓库名称
	 * @param fileUrl	生成文件url
	 * @param file		File
	 * @param uploadNo  上传文件编号，为了获文件进度条（唯一标识）
	 * @param fileSize	文件大小（单位 KB）
	 * @date: 2021/3/19 10:36
	 * @return: void
	 */
	@SneakyThrows
	public void putObject(String bucketName, String fileUrl, File file,String uploadNo,
						  Long fileSize) {
		ossClient.putObject(new PutObjectRequest(bucketName,
				fileUrl, file).withProgressListener(new PutObjectProgressListener(
				uploadNo, fileSize)));
	}


	/** 
	 * 生成过期URL链接地址
	 * @param bucketName 仓库名称
	 * @param key
	 * @date: 2021/3/19 10:37
	 * @return: java.lang.String 
	 */
	@SneakyThrows
	public String generatePresignedUrl(String bucketName, String key) {
		
		Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);	
		return ossClient.generatePresignedUrl(bucketName, key, expiration).toString();
	}

	/**
	 *  创建仓库
	 * @param bucketName  仓库名称
	 * @date: 2021/3/19 10:39
	 * @return: void
	 */
	@SneakyThrows
	public void createBucket(String bucketName) {

		ossClient.createBucket(bucketName);
	}

	/**
	 *  删除仓库
	 * @param bucketName  仓库名称
	 * @date: 2021/3/19 10:39
	 * @return: void
	 */
	@SneakyThrows
	public void deleteBucket(String bucketName) {

		ossClient.deleteBucket(bucketName);
	}

	/**
	 * 删除OSS 文件
	 * @param delFileUrl  删除指定文件URL
	 */
	@SneakyThrows
	public void delFile(String delFileUrl){
		// key是文件名
		ossClient.deleteObject(bucketName, delFileUrl);
//		ossClient.shutdown();//关闭连接
	}

	/**
	 * 下载文件
	 * @param downFileUrl
	 * @date: 2021/3/18 17:30
	 * @return: com.aliyun.oss.model.OSSObject
	 */
	public OSSObject getObject(String downFileUrl) {
		OSSObject ossObject = ossClient.getObject(bucketName, downFileUrl);
		return ossObject;
	}


    /**
     * 下载文件
     * @param downFileUrl
     * @date: 2021/3/18 17:30
     * @return: com.aliyun.oss.model.OSSObject
     */
	public void getObject(String downFileUrl, HttpServletResponse response) {

		OSSObject ossObject = ossClient.getObject(bucketName, downFileUrl);
		BufferedInputStream bis = null;
		try {
			String filename=System.currentTimeMillis()+downFileUrl.substring(downFileUrl.lastIndexOf("."));
			response.setContentType("application/octet-stream");
			response.setHeader("Content-disposition", "attachment; filename=" + new String(filename.getBytes("utf-8"), "ISO8859-1"));

			bis = new BufferedInputStream(ossObject.getObjectContent());
			OutputStream os = response.getOutputStream();
			byte[] buffer = new byte[2048];
			int i = bis.read(buffer);
			while (i != -1) {
				os.write(buffer, 0, i);
				i = bis.read(buffer);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		// 关闭OSSClient。
		ossClient.shutdown();
	}

	/**
	 * 通过文件名下载文件到本地
	 *
	 * @param objectName    要下载的文件名
	 * @param localFileName 本地要创建的文件名
	 */
	public void downloadFile(String objectName, String localFileName) {
		// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
		ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName+StrUtil.DOT+"jpg"));
		// 关闭OSSClient。
//		ossClient.shutdown();
	}

	/**
	 * 列举文件下所有的文件根据目录
     */
	public List<String> listFile(String filePath) {

		List<String> fileList = new ArrayList<>(12);
		// 构造ListObjectsRequest请求。
		ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

		// 设置prefix参数来获取fun目录下的所有文件。
		listObjectsRequest.setPrefix(filePath+ StrUtil.SLASH);
		// 列出文件。
		ObjectListing listing = ossClient.listObjects(listObjectsRequest);
		// 遍历所有文件。
		for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
			fileList.add(objectSummary.getKey());
		}
		log.info("遍历所有commonPrefix:");
		for (String commonPrefix : listing.getCommonPrefixes()) {
			System.out.println(commonPrefix);
			fileList.add(commonPrefix);
		}
		return fileList;
	}
}
